# -*- coding: utf-8 -*-
"""
This implements the Main Window.
"""
import os

from PyQt4 import QtGui
from PyQt4 import QtCore

from glwidget import GlWidget
from setuppages import PageSetupWindow
from setuppages import ReportSetupWindow

from convexhull import ConvexHull
from convexhull import Region

class MainWindow (QtGui.QMainWindow):
    """
        TODO
    """
    
    def __init__(self, parent=None):
        """
            Constructor
        """
        self.convexhull = ConvexHull()

        self.canvas_left = 0
        self.canvas_right = 0
        self.canvas_top = 0
        self.canvas_bottom = 0
        
        self.backgroundColor = QtGui.QColor(QtCore.Qt.white)
        self.pointsColor = QtGui.QColor(QtCore.Qt.blue)
        self.edgesColor = QtGui.QColor(QtCore.Qt.green)
        self.pointsSize = 5
        
        self.removePoints = False
        self.sorting = "Merge"
        
        self.convexhullshow = True
        self.sorting = True
        self.region = True
        self.quantity = True
        self.time = True 
           
        
        super(MainWindow, self).__init__(parent)
        self.setObjectName("MainWindow")
        self.resize(1020, 800)
        self.setWindowTitle(QtGui.QApplication.translate( "MainWindow",
                  "Convex Hull", None, QtGui.QApplication.UnicodeUTF8 ) ) 
 
        self.centralwidget = QtGui.QWidget(self)
        self.setCentralWidget(self.centralwidget)


        self.widget = QtGui.QWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(0, 0, 1015, 785))
        self.vboxlayout = QtGui.QVBoxLayout(self.widget)
                
        self.glwidget = GlWidget(self.widget)
        self.glwidget.setGeometry(QtCore.QRect(2, 2, 782, 742))

        self.browser = QtGui.QTextBrowser(self.widget)
        self.browser.setGeometry(QtCore.QRect(790, 2, 220, 400))

        self.convex_widget = QtGui.QWidget(self.widget)
        self.convex_widget.setGeometry(QtCore.QRect(790, 405, 220, 140))

        self.algorithm_label = QtGui.QLabel("Convex Hull: ", self.convex_widget)
        self.algorithm_label.setGeometry(QtCore.QRect(0, 10, 80, 25))

        self.algorithm_combobox = QtGui.QComboBox(self.convex_widget)
        self.algorithm_combobox.setGeometry(QtCore.QRect(110, 10, 100, 25))
        self.algorithm_combobox.addItem("Jarvis")
        self.algorithm_combobox.addItem("Scan")
        self.algorithm_combobox.setToolTip("Algorithm for convex hull problem")

        self.points_quantity_label = QtGui.QLabel("Quantity of Points",self.convex_widget)
        self.points_quantity_label.setGeometry(QtCore.QRect(0, 40, 220, 25))

        self.quantity_textedit = QtGui.QLineEdit(self.convex_widget)
        self.quantity_textedit.setGeometry(QtCore.QRect(110, 40, 100, 25))
        
        self.region_combobox = QtGui.QComboBox(self.convex_widget)
        self.region_combobox.setGeometry(QtCore.QRect(0, 70, 100, 30))
        self.region_combobox.addItem("Space")        
        self.region_combobox.addItem("Disk")
        self.region_combobox.addItem("Circle")
        self.region_combobox.addItem("Triangle")
        self.region_combobox.addItem("Square")        

        self.generate_points_buttom = QtGui.QPushButton("Generate", self.convex_widget)
        self.generate_points_buttom.setGeometry(QtCore.QRect(110, 70, 100, 30))
        self.connect(self.generate_points_buttom, QtCore.SIGNAL("clicked()"), self.generatePoints)      


        self.convexhull_buttom = QtGui.QPushButton("Generate Convex Hull", self.convex_widget)
        self.convexhull_buttom.setGeometry(QtCore.QRect(40, 110, 150, 30))
        self.connect(self.convexhull_buttom, QtCore.SIGNAL("clicked()"), self.generateConvexHull)

        self.output_browser = QtGui.QTextBrowser(self.widget)
        self.output_browser.setGeometry(QtCore.QRect(790, 550, 220, 195))


        self.menubar = QtGui.QMenuBar(self)
        self.menubar.setGeometry( QtCore.QRect(0, 0, 468, 25) )

        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenu.setTitle( QtGui.QApplication.translate( "MainWindow",
                                "&File", None, QtGui.QApplication.UnicodeUTF8) )

        self.actionNew = QtGui.QAction(self)
        self.fileMenu.addAction(self.actionNew)
        self.actionNew.setText(QtGui.QApplication.translate( "MainWindow",
                                "&New", None, QtGui.QApplication.UnicodeUTF8) )
        self.connect(self.actionNew, QtCore.SIGNAL("activated()"), self.newFile)
                                
        self.actionOpen = QtGui.QAction(self)
        self.fileMenu.addAction(self.actionOpen)
        self.actionOpen.setText(QtGui.QApplication.translate( "MainWindow",
                                "&Open", None, QtGui.QApplication.UnicodeUTF8) )
        self.connect(self.actionOpen, QtCore.SIGNAL("activated()"), self.openFile)
        
        self.actionSave = QtGui.QAction(self)
        self.fileMenu.addAction(self.actionSave)
        self.actionSave.setText(QtGui.QApplication.translate( "MainWindow",
                                "&Save", None, QtGui.QApplication.UnicodeUTF8) )
        self.connect(self.actionSave, QtCore.SIGNAL("activated()"), self.saveFile)        

       
        self.actionQuit = QtGui.QAction(self)
        self.actionQuit.setObjectName("actionQuit")
        self.fileMenu.addAction(self.actionQuit)
        self.actionQuit.setText(QtGui.QApplication.translate( "MainWindow",
                                "&Quit", None, QtGui.QApplication.UnicodeUTF8) )

        self.projectMenu = self.menuBar().addMenu("&Project")
        self.projectMenu.setTitle( QtGui.QApplication.translate( "MainWindow",
                                "&Project", None, QtGui.QApplication.UnicodeUTF8) )


        self.actionAboutBox = QtGui.QAction(self)
        self.projectMenu.addAction(self.actionAboutBox)
        self.actionAboutBox.setText(QtGui.QApplication.translate( "MainWindow",
                                "&About", None, QtGui.QApplication.UnicodeUTF8) )
        self.connect(self.actionAboutBox, QtCore.SIGNAL("activated()"), self.aboutBox)

        self.actionPageSetup = QtGui.QAction(self)
        self.projectMenu.addAction(self.actionPageSetup)
        self.actionPageSetup.setText(QtGui.QApplication.translate( "MainWindow",
                                "&Page Setup", None, QtGui.QApplication.UnicodeUTF8) )
        self.connect(self.actionPageSetup, QtCore.SIGNAL("activated()"), self.pageSetup)
        self.pageSetupWindow = PageSetupWindow(self)



        self.actionReportSetup = QtGui.QAction(self)
        self.projectMenu.addAction(self.actionReportSetup)
        self.actionReportSetup.setText(QtGui.QApplication.translate( "MainWindow",
                                "&Report Setup", None, QtGui.QApplication.UnicodeUTF8) )
        self.connect(self.actionReportSetup, QtCore.SIGNAL("activated()"), self.reportSetup)  
        self.reportSetupWindow = ReportSetupWindow()

        self.actionGenerateReport = QtGui.QAction(self)
        self.projectMenu.addAction(self.actionGenerateReport)
        self.actionGenerateReport.setText(QtGui.QApplication.translate( "MainWindow",
                                "&Generate Report", None, QtGui.QApplication.UnicodeUTF8) )
        self.connect(self.actionGenerateReport, QtCore.SIGNAL("activated()"), self.generateReport)  


        self.statusbar = QtGui.QStatusBar(self)
        self.setStatusBar(self.statusbar)

        QtCore.QMetaObject.connectSlotsByName(self)
        
        self.filename = None

    def on_actionQuit_triggered(self):
        """
            This metod is called when the action actionQuit is triggered, 
            ie when the Quit menu entry is triggered.

            The control of the called is doing by QT.
        """
        exit()

    def newFile(self):
        """
            This metod is called when the action actionNew activated.
            
            This create a new file with data of a curve.
        """
        # Limpa o browser
        self.browser.clear()

        # Limpa o widget
        self.convexhull.points = []
        self.convexhull.edges = []
        self.glwidget.show = False
        self.glwidget.glDraw() 
        
        
    def openFile(self):
        """
            This metod is called when the action actionOpen activated.
            
            This open a file with data of a curve.
        """
        self.convexhull.clear()
        self.glwidget.show = False
        
        dir = os.path.dirname(self.filename) if self.filename is not None else "."

        # Lista de formatos de Imagens suportados
        formats = ["*.txt", "*.inp"]
        
        # Seleciona um arquivo e configura a caixa de dialogo para abertura deste
        filename = unicode(QtGui.QFileDialog.getOpenFileName(self,
                            "Open File", dir,
                            "File types: %s" % " ".join(formats)))
        
        # Se um arquivo for selecionado chama o metodo para le-lo
        if filename:
            content = self.loadFile(filename)
    
        self.glwidget.drawer.setPointsColor( float( self.pointsColor.red() ) / 255,
                                        float( self.pointsColor.green() ) / 255, 
                                        float( self.pointsColor.blue() ) / 255)    
    
        self.glwidget.drawer.setEdgesColor( float( self.edgesColor.red() ) / 255,
                                        float( self.edgesColor.green() ) / 255, 
                                        float( self.edgesColor.blue() ) / 255)          
        self.glwidget.glDraw()

    def loadFile(self, filename=None):
        if filename is None:
            action = self.sender()
            if isinstance(action, QAction):
                filename = unicode(action.data().toString())
            else:
                return
        
        if filename:
            self.filename = None
            source = open(filename, "r")
            self.browser.clear()
            
            self.browser.append("CONVEX HULL")
            
            algorithm = source.readline().split("#")[0]
            self.browser.append("Algorithm:  %s" % algorithm)
            self.algorithm_combobox.setEditText(algorithm)
            
            line = source.readline().split("#")[0].split()
            self.edgesColor = QtGui.QColor(int(line[0]), int(line[1]), int(line[2]))
            self.setColor(self.edgesColor, self.edges_color_label)              
            self.browser.append("Color Edges (RGB):  ( %s,  %s,  %s )" % (self.edgesColor.red(), self.edgesColor.green(), self.edgesColor.blue()) )

            line = source.readline().split("#")[0].split()
            self.pointsColor = QtGui.QColor(int(line[0]), int(line[1]), int(line[2]))
            self.setColor(self.pointsColor, self.pointsColorLabel)              
            self.browser.append("Color Points (RGB):  ( %s,  %s,  %s )" % (self.pointsColor.red(), self.pointsColor.green(), self.pointsColor.blue()) )

            points_size = source.readline().split(" ")[0]
            self.browser.append("Points Size:  %s"%points_size)

            self.browser.append("List of Control Points:")
            line = source.readline() # just comment
            line = source.readline().split()
            cp_list = []
            while (line):
                point = [0.0, 0.0]
                for i in range(2):
                    point[i] = float(line[i])
                cp_list.append(point)
                self.browser.append("( %s,   %s)" % 
                                     ( point[0], point[1]))
                line = source.readline().split()
                self.convexhull.points.append(point)
            source.close()
            
        return ( algorithm, points_size, cp_list )
                 
    def saveFile(self):
        dirname = os.path.dirname(self.filename) if self.filename is not None else "."
        formats = ["*.txt", "*.inp", "*.png", "*.jpg"]
        filename = unicode(QtGui.QFileDialog.getSaveFileName(self,
                            "Save Project", dirname,
                            "File types: %s" % " ".join(formats)))

        filetype = filename[-3:]
        if filetype in ["png", "jpg"]:
            self.saveImage(filename, dirname, filetype)
        elif filetype in ["txt", "inp"]:
            self.saveProject(filename, dirname)
        else:
            print "ERROR, undefined type"

                            
                            
    def saveProject(self, filename, dirname):
        source = open(filename, "w")
        source.write("%s \t\t# Algorithm\n" % self.algorithm_combobox.currentText() )    
        source.write("%s %s %s \t# Colors of convex hull (RGB; varing between 0 and 255)\n" % ( self.edgesColor.red(), self.edgesColor.green(), 
                                 self.edgesColor.blue() ) )
        source.write("%s %s %s \t# Colors of points (equals of the colors of convex hull)\n"  % ( self.pointsColor.red(), self.pointsColor.green(), 
                                    self.pointsColor.blue() ) )
                                    
        source.write("%s \t\t\t# Size of Points\n" % self.point_size_spinbox.value() )
        source.write("# List of Points:\n")
        for point in self.convexhull.points:
            source.write( "%s  %s\n" % ( point[0], point[1]) )
        source.close()

    def saveImage(self, filename, dirname, filetype):
        im = self.glwidget.grabFrameBuffer()
        im.save(filename, filetype)

    def aboutBox(self):
        print "About"

    def generateReport(self):
        print "Report"

    def pageSetup(self):
        self.pageSetupWindow.show() 


    def reportSetup(self):
        self.reportSetupWindow.show() 


    def setJarvis(self):
        self.glwidget.painter.opened = True
        self.glwidget.glDraw()

    def setScan(self):
        self.glwidget.painter.opened = False   
        self.glwidget.glDraw()     
        
        
    def generatePoints(self):
        """
        """
        region = Region()
        points = []
        if self.region_combobox.currentText() == "Space":      
            points = region.generateSpace( int(self.quantity_textedit.text()) )
        elif self.region_combobox.currentText() == "Disk": 
            points = region.generateDisk( int(self.quantity_textedit.text()) )
        elif self.region_combobox.currentText() == "Circle": 
            points = region.generateCircle( int(self.quantity_textedit.text()) )
        elif self.region_combobox.currentText() == "Triangle": 
            points = region.generateTriangle( int(self.quantity_textedit.text()) )
        elif self.region_combobox.currentText() == "Square": 
            points = region.generateSquare( int(self.quantity_textedit.text()) )

        for point in points:
            self.convexhull.points.append(point)

        self.glwidget.glDraw()        
        
    def generateConvexHull(self):
        """
            This metod is called when the buttom Generate Curve (self.buttom) 
            is clicked.
            
            This show a curve on widgwet.
        """
        if self.algorithm_combobox.currentText() == "Jarvis":
            self.convexhull.generateConvexHull("JARVIS")
        elif self.algorithm_combobox.currentText() == "Scan":
            self.convexhull.generateConvexHull("SCAN")


        self.glwidget.show = True
        self.glwidget.glDraw()        
        
        
